#include "activity_config.h"
#include "time_module.h"
#include "string_common.h"
#include "log.h"

CTimeSpace::CTimeSpace()
{
	begin_time_ = 0;
	end_time_ = 0;
	week_day_ = 0;
}

CTimeSpace::~CTimeSpace()
{
}

CActivityTpl::CActivityTpl()
{
	activity_id_ = 0;

	cycle_ = 0;
	cycle_begin_time_ = 0;
	join_time_ = 0;
	maxlimit_lv_ = 0;
	minlimit_lv_ = 0;
}

CActivityTpl::~CActivityTpl()
{

}

bool CActivityTpl::LoadFromJsonNode(const Json::Value& activity_json)
{
	activity_id_ = activity_json["id"].asInt();
	type_start_ = activity_json["type_start"].asInt();
	join_time_ = activity_json["joinAmount_limit"].asInt();

	Json::Value lv_json = activity_json["level_limit"];
	if (lv_json.size() != 2)
	{
		minlimit_lv_ = 0;
		maxlimit_lv_ = 0;
	}
	else
	{
		int32_t index = 0;
		minlimit_lv_ = lv_json[index++].asInt();
		maxlimit_lv_ = lv_json[index++].asInt();
	}

	Json::Value dates = activity_json["dates"];
	for (int32_t i = 0; i < dates.size(); ++i)
	{
		int32_t day = dates[i].asInt();
		dates_.push_back(day);
		LOG_DEBUG("default","day:%d", day);
	}

	Json::Value week_days = activity_json["week_days"];
	for (int32_t i = 0; i < week_days.size(); ++i)
	{
		int32_t week = week_days[i].asInt();
		if (week == 7)
		{
			week = 0;
		}
		weekdays_.push_back(week);
		LOG_DEBUG("default","week:%d", week);
	}

	int32_t begin_time = activity_json["begin_time"].asInt();
	int32_t end_time = activity_json["end_time"].asInt();
	CTimeSpace time_space;
	time_space.set_begin_time(begin_time * 100);
	time_space.set_end_time(end_time * 100);
	time_space_list_.push_back(time_space);

	return true;
}

bool CActivityTpl::CanJoinInActivity(tm& t) const
{
	if (dates_.empty() == false)
	{
		int32_t yyyymmdd = (t.tm_year + 1900) * 10000 + (t.tm_mon + 1) * 100 + t.tm_mday;
		if (std::find(dates_.begin(), dates_.end(), yyyymmdd) == dates_.end())
		{
			return false;
		}
	}
	if (weekdays_.empty() == false)
	{
		if (std::find(weekdays_.begin(), weekdays_.end(), t.tm_wday) == weekdays_.end())
		{
			return false;
		}
	}

	return true;
}

int32_t CActivityTpl::GetNowCycleBeginTime0(int32_t now) const
{
	if (time_space_list().size() <= 0) {
		return 0;
	}

	const CTimeSpace& time_space = time_space_list()[0];

	if (cycle_days_.size() > 0) {
		int32_t cycle_day = cycle_days_[0];
		return CActivityConfig::GetNowCycleTime(now, cycle_begin_time_, cycle_, cycle_day, time_space.begin_time() / 10000, time_space.begin_time() / 100 % 100);
	}
	else if (weekdays_.size() > 0) {
		int32_t week_day = weekdays_[0];
		return CActivityConfig::GetNowWeekTime(now, week_day, time_space.begin_time() / 10000, time_space.begin_time() / 100 % 100);
	}

	return 0;
}

int32_t CActivityTpl::GetNextCycleBeginTime0(int32_t now) const
{
	if (time_space_list().size() <= 0) {
		return 0;
	}

	const CTimeSpace& time_space = time_space_list()[0];

	if (cycle_days_.size() > 0) {
		int32_t cycle_day = cycle_days_[0];
		return CActivityConfig::GetNextCycleTime(now, cycle_begin_time_, cycle_, cycle_day, time_space.begin_time() / 10000, time_space.begin_time() / 100 % 100);
	}
	else if (weekdays_.size() > 0) {
		int32_t week_day = weekdays_[0];
		return CActivityConfig::GetNowWeekTime(now, week_day, time_space.begin_time() / 10000, time_space.begin_time() / 100 % 100) + 7 * 24 * 3600;
	}

	return 0;
}



bool CActivityTpl::IsOpen(tm& t) const
{
	if (dates_.empty() == false)
	{
		int32_t yyyymmdd = (t.tm_year + 1900) * 10000 + (t.tm_mon + 1) * 100 + t.tm_mday;
		if (std::find(dates_.begin(), dates_.end(), yyyymmdd) == dates_.end())
		{
			return false;
		}
	}
	if (weekdays_.empty() == false)
	{
		if (std::find(weekdays_.begin(), weekdays_.end(), t.tm_wday) == weekdays_.end())
		{
			return false;
		}
	}
	if (time_space_list_.empty() == false)
	{
		int32_t hh24miss = t.tm_hour * 10000 + t.tm_min * 100 + t.tm_sec;
		bool find_time = false;
		for (TTimeSpaceList::const_iterator iter = time_space_list_.begin(); iter != time_space_list_.end(); ++iter)
		{
			const CTimeSpace& time_space = *iter;
			if (time_space.begin_time() > hh24miss ||
				time_space.end_time() < hh24miss)
			{
				continue;
			}
			find_time = true;
			break;
		}
		if (find_time == false)
		{
			return false;
		}
	}
	return true;
}

int32_t CActivityTpl::GetNextFireTime() const
{
	time_t cur_time = CUR_SEC;
	time_t fire_time = dates_.empty() ? cur_time : ::common::RebuildTime(dates_.front(), 0);
	for (int32_t i = 0; i < WEEK_DAY_NUM; ++i)
	{
		tm* fire_tm = localtime(&fire_time);
		if (NULL == fire_tm)
		{
			fire_time += 24 * 60 * 60;
			continue;
		}
		if (dates_.empty() == false)
		{
			int32_t yyyymmdd = (fire_tm->tm_year + 1990) * 10000 + (fire_tm->tm_mon + 1) * 100 + fire_tm->tm_yday;
			if (std::find(dates_.begin(), dates_.end(), yyyymmdd) == dates_.end())
			{
				fire_time += 24 * 60 * 60;
				continue;
			}
		}
		if (weekdays_.empty() == false)
		{
			if (std::find(weekdays_.begin(), weekdays_.end(), fire_tm->tm_wday) == weekdays_.end())
			{
				fire_time += 24 * 60 * 60;
				continue;
			}
		}
		if (time_space_list_.empty() == false)
		{
			for (TTimeSpaceList::const_iterator iter = time_space_list_.begin(); iter != time_space_list_.end(); ++iter)
			{
				const CTimeSpace& time_space = *iter;
				time_t fire_time = ::common::RebuildTime(fire_tm, time_space.begin_time());
				if (fire_time > cur_time)
				{
					return fire_time;
				}
			}
		}
		else
		{
			if (fire_time > cur_time)
			{
				return fire_time;
			}
		}
		fire_time += 24 * 60 * 60;
	}
	return 0;
}

CActivityConfig::CActivityConfig()
{

}

CActivityConfig::~CActivityConfig()
{

}

bool CActivityConfig::LoadFromFile()
{
	activity_map_.clear();
	Json::Value tmp_json = ReadJsonFile("data/activity/Activity_opentime.json");
	std::string jsonstr = JsonWriter(tmp_json);
	if (tmp_json != Json::nullValue)
	{
		for (int32_t i = 1; i <= tmp_json.size(); ++i)
		{
			std::string index = ::common::ToString(i);
			CActivityTpl activity_tpl;
			activity_tpl.LoadFromJsonNode(tmp_json[index]);

			activity_map_.insert(std::make_pair(activity_tpl.activity_id(), activity_tpl));
		}
		return true;
	}
	else
	{
		return false;
	}
	return false;
}

const CActivityTpl* CActivityConfig::GetActivityByID(int32_t activity_id) const
{
	TActivityMap::const_iterator iter = activity_map_.find(activity_id);
	if (iter == activity_map_.end())
	{
		return NULL;
	}
	return &(iter->second);
}


int32_t CActivityConfig::GetNowWeekTime(int32_t now, int32_t weekday, int32_t hour, int32_t min)
{
	int32_t ready_time = ::common::GetWeekSundyTime(now);
	ready_time += ((weekday * 24 + hour) * 60 + min) * 60;
	return ready_time;
}

int32_t CActivityConfig::GetNowCycleTime(int32_t now, int32_t cycle_begin_time, int32_t cycle, int32_t cycle_day, int32_t hour, int32_t min)
{
	if (cycle <= 0) {
		return 0;
	}
	int32_t cycle_idx = (now - cycle_begin_time) / (cycle * 24 * 3600);
	return cycle_begin_time + cycle_idx*cycle * 24 * 3600 + cycle_day * 24 * 3600 + hour * 3600 + min * 60;
}

int32_t CActivityConfig::GetNextCycleTime(int32_t now, int32_t cycle_begin_time, int32_t cycle, int32_t cycle_day, int32_t hour, int32_t min)
{
	if (cycle <= 0) {
		return 0;
	}
	int32_t cycle_idx = (now - cycle_begin_time) / (cycle * 24 * 3600);
	return cycle_begin_time + (cycle_idx + 1)*cycle * 24 * 3600 + cycle_day * 24 * 3600 + hour * 3600 + min * 60;
}
